package com.apes.scm.account.account.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.repository.CustomRepository;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.hr.area.model.DeptArea;
import com.apes.hr.area.model.DeptAreaItem;
import com.apes.hr.area.repository.DeptAreaItemRepository;
import com.apes.hr.area.repository.DeptAreaRepository;
import com.apes.scm.account.account.model.Stock;
import com.apes.scm.account.account.repository.StockRepository;
import com.apes.scm.masterdata.product.model.Classify;
import com.apes.scm.masterdata.product.repository.ClassifyRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.masterdata.stock.repository.LocationRepository;
import com.apestech.framework.json.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

@Service("stockAppService")
public class StockAppService extends DomainService {

    @Autowired
    private StockRepository stockRepository;

    @Autowired
    private LocationRepository locationRepository;

    @Autowired
    private ClassifyRepository classifyRepository;

    /**
     * 查询库存账的三级商品品类
     */
    public JSONArray findStockClassify(SimpleRequest request) {
        List<String> classifyIds = stockRepository.findStockClassify(request.get("deptId").toString());
        List<Classify> classifyList = classifyRepository.findAll(JpaDsl.toCriteria("id", "IN", classifyIds));
        JSONArray jsonArray = new JSONArray();
        classifyList.forEach(classify -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",classify.getId());
            jsonObject.put("name",classify.getName());
            jsonArray.add(jsonObject);
        });
        return jsonArray;
    }

    /**
     * 根据三级品类统计四五级库存账数据
     */
    public JSONArray findStockClassifyData(SimpleRequest request) {
        Location location = locationRepository.findAll(JpaDsl.toCriteria("depot.dept.id", "EQ", request.get("deptId").toString(),
                "usage.id", "EQ", "1")).get(0);
        List<Stock> stocks = stockRepository.findByClassify3(location.getId(), request.get("classify").toString());
        JSONArray jsonArray = new JSONArray();
        //四级
        List<Classify> classify4 = stocks.stream().map(stock -> stock.getProduct().getClassify().getParents()).collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparing(classify->classify.getId()))), ArrayList::new));
        classify4.forEach(classify -> {
            JSONObject jsonObject = new JSONObject();
            JSONArray classifyItem = new JSONArray();
            jsonObject.put("id",classify.getId());
            jsonObject.put("name",classify.getName());
            List<Stock> stockList = stocks.stream().filter(stock -> stock.getProduct().getClassify().getParents().getId().equals(classify.getId())).collect(Collectors.toList());
            List<Classify> classify5 = stockList.stream().map(stock -> stock.getProduct().getClassify()).collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparing(e->e.getId()))), ArrayList::new));
            classify5.forEach(e->{
                JSONObject item = new JSONObject();
                item.put("id",e.getId());
                item.put("name",e.getName());
                List<Stock> list = stockList.stream().filter(stock -> stock.getProduct().getClassify().getId().equals(e.getId())).collect(Collectors.toList());
                item.put("usableQty",list.stream().mapToDouble(Stock::getUsableQty).sum());
                item.put("custodyQty",list.stream().mapToDouble(Stock::getCustodyQty).sum());
                classifyItem.add(item);
            });
            jsonObject.put("obj",classifyItem);
            jsonArray.add(jsonObject);
        });
        return jsonArray;
    }

    /**
     * 搜索库存账(分类或名字或id)
     */
    public JSONObject findByNameOrId(SimpleRequest request) {
        JSONObject jo = request.getJO();
        Location location = locationRepository.findAll(JpaDsl.toCriteria("depot.dept.id", "EQ", jo.getString("deptId"),
                "usage.id", "EQ", "1")).get(0);

        List<Stock> stocks = new ArrayList<>();
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();

        if (jo.getString("text") != null) {
            stocks = stockRepository.findByNameOrId(location.getId(), jo.getString("text"));
        }else if (jo.getString("classify") != null) {
            stocks = stockRepository.findAll(JpaDsl.toCriteriaByEq("product.classify.id",jo.getString("classify"),"location",location), new Sort(Sort.Direction.DESC, "custodyQty"));
        }
        int page = request.getJO().getInteger("page");
        int size = request.getJO().getInteger("size");
        jsonObject.put("total",stocks.size());
        jsonObject.put("pages",calculatePages(page,size,stocks));
        jsonObject.put("usableQty",stocks.size()==0?0:stocks.stream().mapToDouble(Stock::getUsableQty).sum());
        jsonObject.put("custodyQty",stocks.size()==0?0:stocks.stream().mapToDouble(Stock::getCustodyQty).sum());
        stocks = autoPage(page,size, stocks);

        stocks.forEach(stock -> {
            JSONObject object = new JSONObject();
            object.put("productId",stock.getProduct().getId());
            object.put("productName",stock.getProduct().getName());
            object.put("uom",stock.getProduct().getUom().getName());
            object.put("usableQty",stock.getUsableQty());
            object.put("custodyQty",stock.getCustodyQty());
            object.put("classifyName",stock.getProduct().getClassify().getName());
            jsonArray.add(object);
        });

        jsonObject.put("content",jsonArray);
        jsonObject.put("page",page);
        jsonObject.put("size",size);
        return jsonObject;
    }

    public List autoPage(int page,int size, List list) {
        List result = new ArrayList<>();
        if (list.size() <= size*(page +1)) {
            result  = list.subList(page*size,list.size());
        }else {
            result  = list.subList(page*size,size*(page +1));
        }
        return result;
    }

    public int calculatePages(int page,int size,List stocks) {
        if (stocks.size() == 0) return 0;
        if (stocks.size()<= size) return 1;
        if (stocks.size() > size) return stocks.size()/size + 1;
        return 0;
    }

    /**
     * 统计门店正常库的可用数和保管数
     */
    public Map findSum(SimpleRequest request) {
        Location location = locationRepository.findAll(JpaDsl.toCriteria("depot.dept.id", "EQ", request.get("deptId").toString(),
                "usage.id", "EQ", "1")).get(0);
        return stockRepository.findSum(location.getId());
    }

    public Object queryAll(SimpleRequest request) throws Exception {
        JSONObject jo = request.getJO();
        JSONArray condition = jo.getJSONArray("condition");
        for (Object o : condition) {
            JSONObject jsonObject = (JSONObject)o;
            if ("DEPT_REGION".equals(jsonObject.getString("field"))) {
                List<String> value = jsonObject.getJSONArray("value").toJavaList(String.class);
                List<DeptAreaItem> deptAreaItems = SpringManager.getBean(DeptAreaItemRepository.class).findByDeptAreaIn(value);
                JSONArray deptIds = new JSONArray();
                for (DeptAreaItem deptAreaItem : deptAreaItems) {
                    deptIds.add(deptAreaItem.getDept().getId());
                }
                jsonObject.put("value", deptIds);
            }
        }
        return JSON.toJSON(jo.toJSONString());
    }
}
